﻿using DataType.Actions;
using DataType.CustomEnumType;
using DataType.JudgeResults;
using MapCalclator;
using OprsSimulator.Operators;
using OprsSimulator.OprAttributes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ActionsJudge
{
    internal static class GetOnJudge
    {
        public static List<IJudgeResult> ToJudge(IBasicAction act, List<IOperator> oprs, Map map)
        {
            List<IJudgeResult> judgeResults = new List<IJudgeResult>();

            // 判断数据
            GetOnAction action = (GetOnAction)act;
            IOperator opr = null;
            foreach (IOperator oper in oprs)
            {
                if (oper.ObjID == action.ObjID)
                {
                    opr = oper;
                    break;
                }
            }
            if (opr == null)
            {
                Trace.TraceWarning($"无效裁决：态势中没有ID为{action.ObjID}的算子");
                return new List<IJudgeResult>();
            }
            IOperator targetOpr = null;
            foreach (IOperator oper in oprs)
            {
                if (oper.ObjID == action.TargetObjID)
                {
                    targetOpr = oper;
                    break;
                }
            }
            if (targetOpr == null)
            {
                Trace.TraceWarning($"无效裁决：上车目标算子不存在");
                return new List<IJudgeResult>();
            }
            if (action.Type != ActionType.GetOn)
            {
                Trace.TraceWarning("无效裁决：算子的动作类型有误，应该是上车类型");
                return new List<IJudgeResult>();
            }
            if (!typeof(ICommonAttris).IsAssignableFrom(opr.GetType()) ||
                !typeof(IMoveAttris).IsAssignableFrom(opr.GetType()) ||
                !typeof(IStateAttris).IsAssignableFrom(opr.GetType()))
            {
                Trace.TraceWarning($"无效裁决：算子{action.ObjID}不具有执行上车命令所需要的全部属性");
                return new List<IJudgeResult>();
            }
            if (!typeof(ICommonAttris).IsAssignableFrom(targetOpr.GetType()) ||
                !typeof(ICarryingAttris).IsAssignableFrom(targetOpr.GetType()) ||
                !typeof(IMoveAttris).IsAssignableFrom(targetOpr.GetType()) ||
                !typeof(IStateAttris).IsAssignableFrom(targetOpr.GetType()))
            {
                Trace.TraceWarning($"无效裁决：上车目标算子{action.TargetObjID}不具有搭乘算子需要的全部属性");
                return new List<IJudgeResult>();
            }

            //取得属性
            int curHex = (int)opr.GetType().GetProperty("CurHex").GetValue(opr);
            Color color = (Color)opr.GetType().GetProperty("Color").GetValue(opr);
            int speed = (int)opr.GetType().GetProperty("Speed").GetValue(opr);
            bool stop = (bool)opr.GetType().GetProperty("Stop").GetValue(opr);
            int get_on_remain_time = (int)opr.GetType().GetProperty("GetOnRemainTime").GetValue(opr);
            //int get_off_remain_time = (int)opr.GetType().GetProperty("GetOffRemainTime").GetValue(opr);
            int blood = (int)opr.GetType().GetProperty("Blood").GetValue(opr);
            OprSubType oprSubType = (OprSubType)opr.GetType().GetProperty("Subtype").GetValue(opr);
            MoveStateType moveState = (MoveStateType)opr.GetType().GetProperty("MoveState").GetValue(opr);
            bool keep = (bool)opr.GetType().GetProperty("Keep").GetValue(opr);

            int targetHex = (int)targetOpr.GetType().GetProperty("CurHex").GetValue(targetOpr);
            OprType targetType = (OprType)targetOpr.GetType().GetProperty("Type").GetValue(targetOpr);
            Color targetColor = (Color)targetOpr.GetType().GetProperty("Color").GetValue(targetOpr);
            int targetSpeed = (int)targetOpr.GetType().GetProperty("Speed").GetValue(targetOpr);
            bool targetStop = (bool)targetOpr.GetType().GetProperty("Stop").GetValue(targetOpr);
            int targetGetOnRemainTime = (int)targetOpr.GetType().GetProperty("GetOnRemainTime").GetValue(targetOpr);
            int targetGetOffRemainTime = (int)targetOpr.GetType().GetProperty("GetOffRemainTime").GetValue(targetOpr);
            int loadingCapacity = (int)targetOpr.GetType().GetProperty("LoadingCapacity").GetValue(targetOpr);
            List<OprSubType> validPassengerTypes = (List<OprSubType>)targetOpr.GetType().GetProperty("ValidPassengerTypes").GetValue(targetOpr);
            Dictionary<OprSubType, int> maxPassengerNums = (Dictionary<OprSubType, int>)targetOpr.GetType().GetProperty("MaxPassengerNums").GetValue(targetOpr);
            List<int> passengerIDs = (List<int>)targetOpr.GetType().GetProperty("PassengerIDs").GetValue(targetOpr);
            bool targetKeep = (bool)targetOpr.GetType().GetProperty("Keep").GetValue(targetOpr);
            MoveStateType targetMoveState = (MoveStateType)targetOpr.GetType().GetProperty("MoveState").GetValue(targetOpr);
            List<int> targetGetOnPartnerId = (List<int>)targetOpr.GetType().GetProperty("GetOnPartnerId").GetValue(targetOpr);

            bool getOnFlag = true;
            if (targetType != OprType.Vehicle)
            {
                Trace.TraceWarning($"无效裁决：上车目标算子不是车辆");
                getOnFlag = false;
            }
            if (color != targetColor)
            {
                Trace.TraceWarning($"无效裁决：上车算子{action.ObjID}和目标算子{action.TargetObjID}不是同一阵营");
                getOnFlag = false;
            }
            if (curHex != targetHex)
            {
                Trace.TraceWarning($"无效裁决：上车算子{action.ObjID}与车辆算子{action.TargetObjID}不在同一格");
                getOnFlag = false;
            }
            if (speed > 0 || !stop)
            {
                Trace.TraceWarning($"无效裁决：不处于静止状态的算子不可下达上车命令");
                getOnFlag = false;
            }
            if (targetSpeed > 0 || !targetStop)
            {
                Trace.TraceWarning($"无效裁决：不处于静止状态的算子不可作为上车目标");
                getOnFlag = false;
            }
            if (moveState == MoveStateType.March || targetMoveState == MoveStateType.March)
            {
                Trace.TraceWarning($"无效裁决：行军状态的算子不可执行上车命令或作为上车目标");
                getOnFlag = false;
            }
            if (get_on_remain_time > 0) 
            {
                Trace.TraceWarning($"无效裁决：正在上车的算子{action.ObjID}不可执行上车命令");
                getOnFlag = false;
            }
            //if (targetGetOnRemainTime > 0 || targetGetOffRemainTime > 0)
            //{
            //    Trace.TraceWarning($"无效裁决：正在上车或者下车的算子{action.TargetObjID}不可作为上车命令的目标");
            //    getOnFlag = false;
            //}
            if (keep || targetKeep) 
            {
                Trace.TraceWarning($"无效裁决：上车算子或者上车目标算子被压制");
                getOnFlag = false;
            }
            if (!validPassengerTypes.Contains(oprSubType))
            {
                Trace.TraceWarning($"无效裁决：上车算子{action.ObjID}不属于上车目标算子{action.TargetObjID}的可承载类型");
                getOnFlag = false;
            }
            else
            {
                int num = 0;
                foreach (int id in passengerIDs)
                {
                    foreach (IOperator oper in oprs)
                    {
                        if (oper.ObjID == id)
                        {
                            if ((OprSubType)oper.GetType().GetProperty("Subtype").GetValue(oper) == oprSubType) num++;
                        }
                    }
                }
                foreach (int id in targetGetOnPartnerId)
                {
                    foreach (IOperator oper in oprs)
                    {
                        if (oper.ObjID == id)
                        {
                            if ((OprSubType)oper.GetType().GetProperty("Subtype").GetValue(oper) == oprSubType) num++;
                        }
                    }
                }
                if (maxPassengerNums[oprSubType] <= num)
                {
                    Trace.TraceWarning($"无效裁决：上车目标算子{action.TargetObjID}已达到最大可承载数");
                    getOnFlag = false;
                }
            }
            if(blood > loadingCapacity)
            {
                Trace.TraceWarning($"无效裁决：上车算子{action.ObjID}的班数大于上车目标算子{action.TargetObjID}的承载能力");
                getOnFlag = false;
            }

            GetOnJudgeResult getOnJudgeResult = new GetOnJudgeResult(action.ObjID, getOnFlag, action.TargetObjID);
            judgeResults.Add(getOnJudgeResult);

            return judgeResults;
        }
    }
}
